home *** CD-ROM | disk | FTP | other *** search
- ;* BORDER.ASM
- ;************************************************************************
- ;* *
- ;* PC Scheme/Geneva 4.00 Borland TASM code *
- ;* *
- ;* (c) 1985-1988 by Texas Instruments, Inc. See COPYRIGHT.TXT *
- ;* (c) 1992 by L. Bartholdi & M. Vuilleumier, University of Geneva *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Window Borders, etc. *
- ;* *
- ;*----------------------------------------------------------------------*
- ;* *
- ;* Created by: John Jensen Date: 1985 *
- ;* Revision history: *
- ;* - 18 Jun 92: Renaissance (Borland Compilers, ...) *
- ;* *
- ;* ``In nomine omnipotentii dei'' *
- ;************************************************************************
- IDEAL
- %PAGESIZE 60, 132
- MODEL medium
- LOCALS @@
-
- INCLUDE "scheme.ash"
-
- CODESEG
-
- ;************************************************************************
- ;* Draw Border *
- ;************************************************************************
- PROC C zborder USES si di, @@line, @@col, @@nlines, @@ncols, @@attr, @@label, @@args
- call get_max_rows C
- mov ch, al
- call get_max_cols C
- mov cl, al
- mov bl, [BYTE @@attr]
- mov dl, [BYTE @@col]
- mov dh, [BYTE @@line]
- dec dl
- dec dh
- mov al, 0dah ; load upper left corner character
- call zcorner
- inc dl
- add dl, [BYTE @@ncols]
- mov al, 0bfh ; load upper right corner character
- call zcorner
- inc dh
- add dh, [BYTE @@nlines]
- mov al, 0d9h ; load lower right corner character
- call zcorner
- dec dl
- sub dl, [BYTE @@ncols]
- mov al, 0c0h ; load lower left corner character
- call zcorner
-
- mov dl, [BYTE @@col] ; reload upper left corner
- mov dh, [BYTE @@line]
- dec dl
- jl @@noleftside
- mov bh, [BYTE @@nlines]
- call zside ; draw the left hand border
- mov dh, [BYTE @@line]
- @@noleftside:
- inc dl
- add dl, [BYTE @@ncols]
- cmp dl, cl
- jae @@norightside
- mov bh, [BYTE @@nlines]
- call zside ; draw the right hand border
- mov dh, [BYTE @@line]
- @@norightside:
- dec dh
- jl @@noupperside
- mov dl, [BYTE @@col]
- mov bh, [BYTE @@ncols]
- call ztop ; draw upper lide
-
- push cx ; saves max rows and cols
- mov bx, [@@label] ; get label
- or bx, bx ; if pointer NULL, no label
- jz @@noupperlabel
- mov dx, [@@ncols]
- xor cx, cx
- @@testlabel:
- cmp [BYTE bx], 0 ; end of string?
- je @@endofstring
- inc cx ; inc count
- inc bx ; inc string pointer
- cmp cx, dx ; compare to window width
- jl @@testlabel
- @@endofstring:
- jcxz @@noupperlabel
- push cx
- mov dh, [BYTE @@line] ; load upper left corner
- mov dl, [BYTE @@col]
- dec dh
- xor bh, bh ; use page 0
- mov ah, 02h
- int IBM_CRT ; put cursor in upleft corner of border
- pop cx
- mov di, [@@label] ; load label offset
- @@writelabel:
- mov ah, 0eh ; Write ASCII Teletype
- mov al, [BYTE di]
- mov bl, [BYTE @@attr] ; load attribute bits just in case
- xor bh, bh
- push cx di
- int IBM_CRT ; display label char
- pop di cx
- inc di
- loop @@writelabel
- @@noupperlabel:
- pop cx
- mov bl, [BYTE @@attr]
- @@noupperside:
- mov dl, [BYTE @@col]
- mov dh, [BYTE @@line]
- add dh, [BYTE @@nlines]
- cmp dh, ch
- ja @@nolowerside
- mov bh, [BYTE @@ncols]
- call ztop
- @@nolowerside:
- ret
- ENDP zborder
-
- ;************************************************************************
- ;* Local Support: Draw a single character at cursor position *
- ;* *
- ;* Input Registers: al - the character to be output *
- ;* bl - the character attributes for the write *
- ;* dl - column *
- ;* dh - row *
- ;* cl - max column *
- ;* ch - max row *
- ;* *
- ;* Registers Modified: ax, si, di *
- ;************************************************************************
- PROC zcorner near
- cmp dl, cl ; ensure char written within CRT
- ja @@return
- cmp dh, ch
- ja @@return
- push bx cx dx
- push ax ; save character to be output
- xor bh, bh
- mov ah, 02h
- int IBM_CRT ; position the cursor
- xor bh, bh
- mov ah, 08h
- int IBM_CRT ; read current char on the screen
- call map_char
- mov si, ax
- pop ax ; recover character to be output
- or si, si
- jl @@putcorner
- call map_char
- mov cl, OFFSET @@next - OFFSET @@table
- mul cl
- add si, ax
- mov al, [@@table+si]
- DATASEG
- @@table DB 0dah, 0c2h, 0c3h, 0c5h, 0c3h, 0c2h, 0c2h, 0c5h, 0c3h, 0c5h, 0c5h
- @@next DB 0c2h, 0bfh, 0c5h, 0b4h, 0b4h, 0c2h, 0c2h, 0c5h, 0c5h, 0b4h, 0c5h
- DB 0c3h, 0c5h, 0c0h, 0c1h, 0c3h, 0c1h, 0c5h, 0c1h, 0c3h, 0c5h, 0c5h
- DB 0c5h, 0b4h, 0c1h, 0d9h, 0b4h, 0c1h, 0c5h, 0c1h, 0c5h, 0b4h, 0c5h
- DB 0c3h, 0b4h, 0c3h, 0b4h, 0b3h, 0c5h, 0c5h, 0c5h, 0c3h, 0b4h, 0c5h
- DB 0c2h, 0c2h, 0c1h, 0c1h, 0c5h, 0c4h, 0c2h, 0c1h, 0c5h, 0c5h, 0c5h
- CODESEG
- @@putcorner:
- mov ah, 09h ; output the corner character
- mov cx, 1
- xor bh, bh
- int IBM_CRT ; write char & attrib to the screen
- pop dx cx bx
- @@return:
- ret
- ENDP zcorner
-
- ;************************************************************************
- ;* Local Support: Draw a border sides *
- ;* *
- ;* Input Registers: dl - column *
- ;* dh - row *
- ;* bl - attribute *
- ;* bh - number of rows *
- ;* cl - max column *
- ;* ch - max row *
- ;* *
- ;* Registers Modified: ax, bh, dl, si *
- ;************************************************************************
- PROC zside near
- @@loop:
- mov al, 0b3h ; load "|" border character
- call zcorner ; output the border character
- inc dh ; increment the row number
- dec bh
- jnz @@loop
- @@return:
- ret
- ENDP zside
-
- ;************************************************************************
- ;* Local Support: Draw a border - Top or Bottom *
- ;* *
- ;* Input Registers: dl - column *
- ;* dh - row *
- ;* bl - attribute *
- ;* bh - number of columns *
- ;* cl - max column *
- ;* ch - max row *
- ;* *
- ;* Registers Modified: ax, cx, si, di *
- ;************************************************************************
- PROC ztop near
- @@loop:
- mov al, 0c4h ; load "-" border character
- call zcorner ; output the border character
- inc dl ; increment the column number
- dec bh
- jnz @@loop
- @@return:
- ret
- ENDP ztop
-
- ;************************************************************************
- ;* Local support: map a border character *
- ;************************************************************************
- PROC map_char near
- mov cx, OFFSET @@next - OFFSET @@table
- lea di, [@@table]
- repne scasb
- mov ax, cx
- dec ax
- ret
- DATASEG
- @@table DB 0c5h, 0b4h, 0c3h, 0c1h, 0c2h, 0c4h, 0b3h, 0d9h, 0c0h, 0bfh, 0dah, 0dah
- LABEL @@next BYTE
- CODESEG
- ENDP map_char
-
- ;************************************************************************
- ;* Save Screen Contents *
- ;* *
- ;* Purpose: To save a rectangular region of the CRT in a string data *
- ;* object. *
- ;* *
- ;* Calling Sequence: save_scr(str_reg, ul_row, ul_col, n_rows, ncols) *
- ;* where str_reg - pointer to string data object *
- ;* which is to receive the screen *
- ;* contents *
- ;* ul_row - row number of the upper left *
- ;* corner of the region to be *
- ;* saved *
- ;* ul_col - column number of the upper left *
- ;* corner of the region to be *
- ;* saved *
- ;* n_rows - number of rows in the region to *
- ;* be saved *
- ;* n_cols - number of columns in the region *
- ;* to be saved *
- ;************************************************************************
- PROC C save_scr USES si di, @@str, @@ulrow, @@ulcol, @@nrow, @@ncol, @@args
- LOCAL @@vidmode:BYTE, @@lastback:BYTE, @@lastfore:BYTE
- call is_graph_mode C
- mov [@@vidmode], al
- mov [@@lastfore], 0fh ; a good guess is bright white
- mov [@@lastback], 0 ; on a black background
-
- mov bx, [@@str] ; create a pointer to the string object
- mov di, [(REG bx).disp]
- mov bx, [(REG bx).page]
- ldpage es, bx
- lea di, [(STRDEF di).buffer]
- mov al, [BYTE @@nrow] ; store #rows & columns into the first two bytes
- stosb
- mov al, [BYTE @@ncol]
- stosb
- mov ax, [@@ulrow] ; adjust number of lines/columns for test conditions
- add [@@nrow], ax
- mov ax, [@@ulcol]
- add [@@ncol], ax
- mov dh, [BYTE @@ulrow]
- @@rowloop:
- mov dl, [BYTE @@ulcol]
- @@colloop:
- push di ; some BIOSes don't save it
- mov ah, 02h
- xor bh, bh ; page 0
- int IBM_CRT ; position the cursor (page zero)
- mov ah, 08h
- xor bh, bh ; page 0
- int IBM_CRT ; "read char/attribute" function
- cmp [@@vidmode], 0
- jz @@textmode
- ; we now have al=char, ah=nonsense.
- ; we have to detect the attribute.
- cmp al, 0dbh ; is it a blot ?
- je @@findbackground
- mov [@@lastback], 0 ; this is a black background
- jmp @@findforeground
-
- @@findbackground:
- mov bh, [@@lastback]
- call tryattr
- je @@igiveup
- mov [@@lastback], ah
- mov ah, 08h ; now REALLY read it
- xor bh, bh ; page 0
- int IBM_CRT
- @@findforeground:
- or al, al
- jne @@goahead
- mov al, 0dbh
- mov bl, [@@lastback]
- call putchar
- @@igiveup:
- mov al, ' '
- jmp @@done
- @@goahead:
- mov bh, [@@lastfore]
- call tryattr
- je @@done
- mov [@@lastfore], ah
- mov bl, ah
- call putchar
- mov bl, [@@lastback]
- or bl, bl
- jz @@done
- push ax
- mov al, 0dbh ; write a blot (restore background)
- call putchar
- pop ax
- @@done:
- mov bl, [@@lastback] ; in case we didn't find anything,
- ; assume previous one is OK
- xor ah, bl ; adjust foreground
- mov cl, 4
- shl bx, cl
- or ah, bl
- and ah, 7fh ; mask off the intensity bit
- @@textmode:
- pop di
- stosw ; store char/attr into output string
- inc dl ; next column
- cmp dl, [BYTE @@ncol]
- jb @@colloop
- inc dh ; next line
- cmp dh, [BYTE @@nrow]
- jb @@rowloop
- ret
- ENDP save_scr
-
- ;************************************************************************
- ;* Local support: test if character is readable *
- ;* Assumes: al = char *
- ;* bh = first attribute to try *
- ;* This routine will test if al can be read at the cursor position, and *
- ;* then write al using attributes bl. AX, BX, CX, DX are preserved. *
- ;* The result is in ZF *
- ;* *
- ;************************************************************************
- PROC tryattr near
- push dx
- xor ah, ah ; ah is current try, bh next one
- mov cx, 16 ; try 16 colors
- @@loop:
- mov bl, bh ; this is how to change
- xor bl, ah
- or bl, 80h ; write using XOR
- mov ah, bh ; new becomes old
- inc bh
- and bh, 0fh ; next guess
- push cx bx ax
- mov ah, 09h ; write new char
- xor bh, bh
- mov cx, 1 ; 1 char
- int IBM_CRT
- pop ax
- push ax
- mov ah, 08h ; read char/attr
- xor bh, bh ; page 0
- int IBM_CRT
- mov dx, ax
- pop ax ; restore old char
- cmp al, dl ; same as before ?
- pop bx cx
- loope @@loop
- pop dx
- ret
- ENDP tryattr
-
- ;************************************************************************
- ;* Local support: write the char al with attributes bl *
- ;************************************************************************
- PROC putchar near
- push ax bx cx
- mov ah, 09h
- xor bh, bh
- or bl, 80h
- mov cx, 1
- int IBM_CRT
- pop cx bx ax
- ret
- ENDP putchar
-
- ;************************************************************************
- ;* Restore Screen Contents *
- ;* *
- ;* Purpose: To restore a rectangular region of the CRT from a string *
- ;* data object. *
- ;* *
- ;* Calling Sequence: rest_scr(str_reg, ul_row, ul_col) *
- ;* where str_reg - pointer to string data object *
- ;* which contains the screen *
- ;* contents *
- ;* ul_row - row number of the upper left *
- ;* corner of the region to be *
- ;* restored *
- ;* ul_col - column number of the upper left *
- ;* corner of the region to be *
- ;* restored *
- ;************************************************************************
- PROC C rest_scr USES si di, @@str, @@ulrow, @@ulcol, @@maxrow, @@maxcol
- LOCAL @@ncol, @@nrow, @@vidmode
- mov [@@vidmode], -1
- mov bx, [@@str] ; create a pointer to the string object
- mov si, [(REG bx).disp]
- mov bx, [(REG bx).page]
- ldpage es, bx
- lea si, [(STRDEF si).buffer]
- xor ax, ax ; recover # rows & col from screen object
- lods [BYTE es:si]
- add ax, [@@ulrow]
- mov [@@nrow], ax
- lods [BYTE es:si]
- add ax, [@@ulcol]
- mov [@@ncol], ax
- mov ax, [@@ulrow] ; adjust # of lines/columns for conditions
- add [@@maxrow], ax
- mov ax, [@@ulcol]
- add [@@maxcol], ax
- xor bx, bx ; char count
- mov dh, [BYTE @@ulrow]
- @@rowloop:
- xor bl, bl
- mov cx, [WORD es:si] ; prev char = first char of line
- mov dl, [BYTE @@ulcol]
- @@colloop:
- lods [WORD es:si] ; fetch char from buffer
- cmp dl, [BYTE @@maxcol] ; line too long for new window?
- jnb @@nextchar
- cmp cx, ax ; same char as previous one ?
- jne @@writechars
- inc bl
- @@nextchar:
- inc dl ; next column
- cmp dl, [BYTE @@ncol]
- jb @@colloop
- @@writechars:
- push ax cx si dx
- sub dl, bl ; position at begin of replication
- xor ax, ax
- xchg al, dh ; ax = row, dx = col
- lea si, [@@vidmode]
- call zputc C, ax, dx, cx, bx, si
- pop dx si ax cx
- mov bl, 1
- inc dl ; next column
- cmp dl, [BYTE @@ncol]
- jb @@colloop
- cmp cx, ax ; last char written ?
- je @@nextline
- mov ax, cx
- jmp @@writechars
- @@nextline:
- inc dh ; next line
- cmp dh, [BYTE @@maxrow] ; line out of window ?
- jnb @@return
- cmp dh, [BYTE @@nrow]
- jb @@rowloop
- @@return:
- ret
- ENDP rest_scr
-
- END